/**
* Copyright © 2018 深圳市巨鼎医疗设备有限公司
*/
package com.zl.websocket.config.websocket;

import java.util.Collections;
import java.util.Set;

import javax.annotation.PreDestroy;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.Topic;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zl.websocket.config.redis.RedisMessageListener;
import com.zl.websocket.entity.WebsocketMessageTransform;
import com.zl.websocket.service.MessageService;
import com.zl.websocket.service.RouteService;
import com.zl.websocket.service.WebsocketSender;

/**
 * websocket消息监听器
 * 
 * @author Zhouych
 * @Date: 2018年6月26日 下午5:16:38
 * @since JDK 1.8
 */
@Component("websocketMessageListener")
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class WebsocketMessageListener implements RedisMessageListener {

	private static final Logger logger = LoggerFactory.getLogger(WebsocketMessageListener.class);

	@Autowired
	@Qualifier(value = "redisTemplate")
	private RedisTemplate<String, Object> redisTemplate;

	@Autowired
	@Qualifier("websocketRouteService")
	private RouteService websocketRouteService;

	@Autowired
	@Qualifier("websocketRouteService")
	private MessageService websocketMessageService;

	@Autowired
	private WebsocketSender websocketSender;

	/**
	 * 完成监听时，先把channel生成并保存到redis中
	 */
	@Override
	public void afterListen() {
		websocketRouteService.instanceInit();
	}

	/**
	 * bean销毁时
	 */
	@PreDestroy
	public void destroy() {
		websocketRouteService.clearAll(websocketRouteService.getInstanceId());
	}

	@Override
	public void onMessage(Message message, byte[] pattern) {
		WebsocketMessageTransform wmt = null;
		try {
			wmt = (WebsocketMessageTransform) redisTemplate.getValueSerializer().deserialize(message.getBody());
			websocketSender.send(wmt);
		} catch (Exception ex) {
			StringBuilder errorMsg = new StringBuilder();
			errorMsg.append("发送websocket消息失败");
			if (null != wmt) {
				try {
					errorMsg.append("，消息内容：").append(new ObjectMapper().writeValueAsString(wmt));
				} catch (JsonProcessingException e) {
				}
				Set<String> userIds = wmt.getUserIds();
				if (null != userIds && !userIds.isEmpty()) {
					for (String userId : userIds) {
						if (StringUtils.isNotBlank(userId)) {
							websocketMessageService.onSendFail(userId, wmt.getPayload());
						}
					}
				}
			}
			logger.error(errorMsg.toString(), ex);
		}
	}

	@Override
	public Set<Topic> getTopics() {
		return Collections.singleton(new ChannelTopic(websocketRouteService.getInstanceId()));
	}

}
